﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace daStaticAnalyser.Analysers
{
    using daStaticAnalyser;
    using daBase.Objects;
    using daBase.Analyser;
    using daSyntaxAnalyser;
    using daSyntaxAnalyser.SyntaxTree;

    [AnalyserDefaultSettings("Средний спен переменных", "test", 0, "test")]
    class SpenAnalyzer : BaseStaticAnalyser
    {
        private void GetData(ISyntaxTreeElement Element)
        {
            if (Element == null)
                return;

            if (Element is StandartVariableExpressionElement)
            {
                String temp = Element.ToString();
                if (!temp.Contains("("))
                {
                    String[] strs = temp.Split('.');
                    if (GlobalVar.Contains(strs[0]) || Vars.Contains(strs[0]))
                    {
                        if (VarNames.Contains(strs[0]))
                        {
                            VarsSpen[strs[0]]++;
                        }
                        else
                        {
                            VarNames.Add(strs[0]);
                            VarsSpen.Add(strs[0], 0);
                        }
                    }
                }
            }            

            foreach (ISyntaxTreeElement element in Element)
            {
                GetData(element);
            }
        }

        List<String> Vars, VarNames;
        Dictionary<String, int> VarsSpen;

        protected override void DoAnalyse(SyntaxTreeArgs e)
        {
            String MethodName = "";
            if (CheckMethod_GetName(e, out MethodName))
            {
                OuterMethodElement Method = e.Element as OuterMethodElement;

                Vars = new List<string>();

                if ((Method.Header is InnerProcedureHeadElement) || (Method.Header is ProcedureTypeElement))
                {
                    List<FunctionVarDeclarationElement> vars;
                    vars = (Method.Header is InnerProcedureHeadElement) ? (Method.Header as InnerProcedureHeadElement).Vars : vars = (Method.Header as ProcedureTypeElement).Vars;
                    if (vars != null)
                    {
                        foreach (FunctionVarDeclarationElement declaration in vars)
                        {
                            foreach (IdElement id in declaration.Ids) Vars.Add(id.ToString());
                        }
                    }
                }                
                
                foreach (var vars in Method.Body.Declarations)
                {
                    if (vars is VarDeclarationsElement)
                    {
                        foreach (var v in (vars as VarDeclarationsElement).Vars)
                        {
                            VarDeclarationElement vardec = v as VarDeclarationElement;
                            foreach (IdElement id in vardec.Ids) Vars.Add(id.ToString());
                        }
                    }
                }

                VarsSpen = new Dictionary<string, int>();
                VarNames = new List<string>();
                GetData((e.Element as OuterMethodElement).Body);

                float rezult = 0;
                int VarCount = VarNames.Count;
                if (VarCount > 0)
                {
                    foreach (String name in VarNames)
                    {
                        rezult += ((float)VarsSpen[name]) / VarCount;
                    }
                }

                AddMetric("Средний спен переменных",
                            rezult,
                            MethodName,
                            e.Element.StartInfo.File,
                            e.Element.StartInfo.Line);
            }
            else
            {
                GlobalVarFind(e.Element);
            }
        }

        protected override void DoFinishAnalyse(EventArgs e)
        {
            GlobalVar.Clear();
        }
    }
}
